Xceed DataGrid for WPF v7.3 Documentation
Welcome to Xceed DataGrid, Editors, and 3D Views for WPF v7.3 / Xceed DataGrid for WPF / Code Snippets / Editing Data

In This Topic
    Editing Data
    In This Topic

    The following page provides a list of examples that demonstrate how to edit data. For more data editing-related information, refer to the Editing and Validating Data Overview topic.

    All examples in this topic assume that the grid is bound to the Orders table of the Northwind database, unless stated otherwise.

    Entering edit when a cell is current

    The following example demonstrates how to enter edit mode only when a cell becomes current by setting the EditTriggers property to CellIsCurrent.

    XAML
    Copy Code
    <Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
      <Grid.Resources>
        <xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
                                        Source="{Binding Source={x:Static Application.Current},
                                         Path=Orders}"/>
      </Grid.Resources>
      <xcdg:DataGridControl x:Name="OrdersGrid"
                            ItemsSource="{Binding Source={StaticResource cvs_orders}}"
                            EditTriggers="CellIsCurrent"/>      
    </Grid>

    Using a masked text box

    The following example demonstrates how to use the MaskedTextBox control outside a grid to allow a user to input a fictitious identity number. The foreground color of the masked text box will change from red when it contains invalid text (HasParsingError), to blue when all required characters have been inputted (IsMaskCompleted), to green when all characters, required and optional, have been inputted (IsMaskFull).

    XAML
    Copy Code
    <Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid"
          xmlns:s="clr-namespace:System;assembly=mscorlib">
      <Grid.Resources>  
    <Style TargetType="{x:Type xcdg:MaskedTextBox}">
          <Style.Triggers>
             <Trigger Property="HasParsingError" Value="True">
                <Setter Property="Foreground" Value="Red" />
             </Trigger>
             <Trigger Property="IsMaskCompleted" Value="True">
               <Setter Property="Foreground" Value="Blue" />
            </Trigger>
           
            <Trigger Property="IsMaskFull" Value="True">
               <Setter Property="Foreground" Value="Green" />
            </Trigger>
         </Style.Triggers>
      </Style>
      </Grid.Resources>
        <xcdg:MaskedTextBox Mask=">LLLL 000000 ??"
                            PromptChar="-"
                            AllowPromptAsInput="True"
                            ResetOnPrompt="True"
                            ResetOnSpace="True"
                            Height="Auto"/>
      </Grid>

    Handling routed edit events

    The following example demonstrates how to subscribe to the Cell.EditBeginning and EditBegun routed events as well as how to handle and cancel them.

    XAML
    Copy Code
    <Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
       <Grid.Resources>
          <xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
                                          Source="{Binding Source={x:Static Application.Current}, Path=Orders}" />
            </Grid.Resources>
       <DockPanel>
          <StackPanel DockPanel.Dock="Top">
             <CheckBox x:Name="handledByRowCheckBox"
                       Content="Events are handled by the rows"
                       IsChecked="False" />
             <CheckBox x:Name="cancelBeginEdit"
                       Content="Cancel BeginEdit event"
                       IsChecked="False" />
          </StackPanel>
          <xcdg:DataGridControl x:Name="OrdersGrid"
                                ItemsSource="{Binding Source={StaticResource cvs_orders}}"
                                xcdg:Cell.EditBeginning="EditBeginning"
                                xcdg:Cell.EditBegun="EditBegun"/>
       </DockPanel>
    </Grid>

    The following code provides the implementation of the EditBeginning and EditBegun event handlers.

    VB.NET
    Copy Code
    Public Sub EditBeginning( ByVal sender As Object, ByVal e As CancelRoutedEventArgs )
       If Me.cancelBeginEdit.IsChecked = True Then
          e.Cancel = True
       End If
       If Me.handledByRowCheckBox.IsChecked = True Then
         e.Handled = True
       End If
       Debug.WriteLine( sender + ": EditBeginning" )
    End Sub
    Public Sub EditBegun( ByVal sender As Object, ByVal e As RoutedEventArgs )
       If Me.handledByRowCheckBox.IsChecked = True Then
         e.Handled = True
       End If
       Debug.WriteLine( sender + ": EditBegun" )
    End Sub
    C#
    Copy Code
    public void EditBeginning( object sender, CancelRoutedEventArgs e )
    {
      e.Cancel = ( this.cancelBeginEdit.IsChecked == true );
      e.Handled = ( this.handledByRowCheckBox.IsChecked == true );
      Debug.WriteLine( sender + ": EditBeginning" );
    }
    public void EditBegun( object sender, RoutedEventArgs e )
    {
      e.Handled = ( this.handledByRowCheckBox.IsChecked ?? true );
      Debug.WriteLine( sender + ": EditBegun" );
    }

    Defining foreign key configurations

    The following example demonstrates how to define foreign key configurations for foreign key descriptions that were automatically created from the constraints extracted from the underlying DataTable.

    XAML
    Copy Code
    <Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
     <Grid.Resources>
        <xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
                                           Source="{Binding Source={x:Static Application.Current}, Path=Orders}"
                                           AutoCreateForeignKeyDescriptions="True"/>
     </Grid.Resources>      
     
     <xcdg:DataGridControl x:Name="OrdersGrid"
                           ItemsSource="{Binding Source={StaticResource cvs_orders}}"
                           AutoCreateForeignKeyConfigurations="True">
        <xcdg:DataGridControl.Columns>
           <xcdg:Column FieldName="EmployeeID"
                        Title="Employee">
              <xcdg:Column.CellContentTemplate>
                 <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                       <TextBlock Text="{Binding FirstName}" />
                       <TextBlock Text=" " />
                       <TextBlock Text="{Binding LastName}" />
                    </StackPanel>
                 </DataTemplate>
              </xcdg:Column.CellContentTemplate>
           </xcdg:Column>
           <xcdg:Column FieldName="CustomerID"
                        Title="Customer">
              <xcdg:Column.ForeignKeyConfiguration>
                 <xcdg:ForeignKeyConfiguration DisplayMemberPath="CompanyName"
                                               ValuePath="CustomerID" />
              </xcdg:Column.ForeignKeyConfiguration>
           </xcdg:Column>
           
           <xcdg:Column FieldName="ShipVia"
                        Title="Shipping Company">
              <xcdg:Column.ForeignKeyConfiguration>
                 <xcdg:ForeignKeyConfiguration DisplayMemberPath="CompanyName"
                                               ValuePath="ShipperID" />
              </xcdg:Column.ForeignKeyConfiguration>
           </xcdg:Column>
        </xcdg:DataGridControl.Columns>
     </xcdg:DataGridControl>
    </Grid>

    Custom key/value mappings

    The following example demonstrates how to bind the grid directly to a BindingList<Person> objects and provide a custom key/value mapping through a ForeignKeyConverter, which will return the appropriate employee first and last names for the provided employee ID.

    XAML
    Copy Code
    <Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
      <Grid.Resources>
         <local:OccupationToStringConverter x:Key="occupationToStringConverter" />
         <local:PersonForeignKeyConverter x:Key="personForeignKeyConverter" />
         <ObjectDataProvider x:Key="occupationValues"
                             MethodName="GetValues"
                             ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
               <x:Type TypeName="local:Occupation" />
            </ObjectDataProvider.MethodParameters>
         </ObjectDataProvider>
      </Grid.Resources>    
     
      <xcdg:DataGridControl x:Name="PersonsGrid"
                            ItemsSource="{Binding Source={x:Static Application.Current}, Path=Persons}">
        <xcdg:DataGridControl.Columns>
           <xcdg:Column FieldName="Occupation">
              <xcdg:Column.CellContentTemplate>
                 <DataTemplate>
                    <TextBlock Text="{Binding Converter={StaticResource occupationToStringConverter}}" />
                 </DataTemplate>
              </xcdg:Column.CellContentTemplate>
              <xcdg:Column.ForeignKeyConfiguration>
                 <xcdg:ForeignKeyConfiguration ItemsSource="{Binding Source={StaticResource occupationValues}}" />
              </xcdg:Column.ForeignKeyConfiguration>
           </xcdg:Column>
           <xcdg:Column FieldName="ReportsTo">
              <xcdg:Column.CellContentTemplate>
                 <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                       <TextBlock Text="{Binding FirstName}" />
                       <TextBlock Text=" " />
                       <TextBlock Text="{Binding LastName}" />
                    </StackPanel>
                 </DataTemplate>
              </xcdg:Column.CellContentTemplate>
              <xcdg:Column.ForeignKeyConfiguration>
                 <xcdg:ForeignKeyConfiguration ItemsSource="{Binding Source={x:Static Application.Current}, Path=Persons}"
                                               ForeignKeyConverter="{StaticResource personForeignKeyConverter}"
                                               ValuePath="PersonID"/>
              </xcdg:Column.ForeignKeyConfiguration>
           </xcdg:Column>
        </xcdg:DataGridControl.Columns>
      </xcdg:DataGridControl>
    </Grid>

    The following code provides the implementation of the PersonForeignKeyConverter class. 

    VB.NET
    Copy Code
    Public Class PersonForeignKeyConverter
                 Inherits ForeignKeyConverter
      Public Overrides Function GetKeyFromValue( value As Object, configuration As ForeignKeyConfiguration ) As Object
        Dim bindingList As PersonBindingList = TryCast( configuration.ItemsSource, PersonBindingList )
        If Not bindingList Is Nothing Then
          Dim person As Person = TryCast( value, Person )
          If Not person Is Nothing Then
            Return person.PersonID
          End If
        End If
        Return -1
      End Function
      Public Overrides Function GetValueFromKey( key As Object, configuration As ForeignKeyConfiguration ) As Object
       Dim bindingList As PersonBindingList = TryCast( configuration.ItemsSource, PersonBindingList )
        If Not bindingList Is Nothing Then
          Try
            Dim personID As Integer = CInt( key )
            Dim person As Person
            For Each person In bindingList
              If person.PersonID = personID Then
                Return person
              End If
            Next person
          Catch e As Exception
            ' key can be nothing
          End Try
        Return Nothing
      End Function
    End Class
    C#
    Copy Code
    public class PersonForeignKeyConverter : ForeignKeyConverter
    {
     public override object GetKeyFromValue( object value, ForeignKeyConfiguration configuration )
     {
       PersonBindingList bindingList = configuration.ItemsSource as PersonBindingList;
       if( bindingList != null )
       {
         Person person = value as Person;
         if( person != null )
         {
           return person.PersonID;
         }
       }
       return -1;
     }
     public override object GetValueFromKey( object key, ForeignKeyConfiguration configuration )
     {
       PersonBindingList bindingList = configuration.ItemsSource as PersonBindingList;
       if( bindingList != null )
       {
         try
         {
           int personID = ( int )key;
           foreach( Person person in bindingList )
           {
             if( person.PersonID == personID )
             {
               return person;
             }
           }
         }
         catch( Exception )
         {
           // key can be null
         }
       }
       return null;
     }
    }

    The following code provides the implementation of the OccupationToStringConverter class.

    VB.NET
    Copy Code
    public class OccupationToStringConverter: IValueConverter
    {
      Public Function Convert( value As Object, targetType As Type, parameter As Object,
                               culture As System.Globalization.CultureInfo ) As Object Implements IValueConverter.Convert
        If( Not value Is Nothing ) AndAlso ( TypeOf value Is Occupation ) Then
          Dim enumString As String = value.ToString()
          ' Start at 1 to ignore the first capitalizes letter.
          Dim i as Integer = 1
          For i To i < enumString.Length - 1
            If char.IsUpper( enumString( i ) ) Then
              enumString = enumString.Insert( i, " " )
              i++
            End If
          Next i
          Return enumString
        End If
        Return Nothing
      End Function
      Public Function ConvertBack( value As Value, targetType As Type, parameter As Object,
                                   culture As System.Globalization.CultureInfo ) As Object Implements IValueConverter.ConvertBack
        Return Binding.DoNothing
      End Function
    End Class
    C#
    Copy Code
    public class OccupationToStringConverter: IValueConverter
    {
     public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
     {
       if( value != null && value is Occupation)
       {
         string enumString = value.ToString();
         // Start at 1 to ignore the first capitalizes letter.
         for( int i = 1; i < enumString.Length - 1; i++ )
         {
           if( char.IsUpper( enumString[ i ] ) )
           {
             enumString = enumString.Insert( i, " " );
             i++;
           }
         }
         return enumString;
       }
       return null;
     }
     public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
     {
       return Binding.DoNothing;
     }
    }